package com.oplink.webems.modules.event.service;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.directwebremoting.Browser;
import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.oplink.webems.modules.alarm.entity.AlarmCurrent;
import com.oplink.webems.modules.cfg.entity.CfgNe;
import com.oplink.webems.modules.cfg.entity.CfgSite;
import com.oplink.webems.modules.event.WebSessionManager;
import com.oplink.webems.modules.event.entity.BaseEvent;

/**
 * 本消息中心也是一个缓冲区
 * 将缓冲区中的数据逐条发到客户端
 * @author yongz
 *
 */
@Component
public class EventCenter implements Runnable {
	
	private LinkedList<BaseEvent> store = new LinkedList<BaseEvent>();
	private final Lock lock = new ReentrantLock();
	private Condition full = lock.newCondition();
	private Condition empty = lock.newCondition();
	
	private static int MAX = 1000;
	
	private void sendToClient(final Object mes){
		//将消息丢给DWR处理
		if(WebSessionManager.sessions != null){
			Browser.withAllSessions(new Runnable(){
				public void run(){
					ScriptBuffer script = new ScriptBuffer();
					script.appendCall("parseMessage", mes);
					for(ScriptSession s : WebSessionManager.sessions){
						s.addScript(script);
					}
				}
			});
		}
	}
	
	public void put(BaseEvent be){
		lock.lock();
		
		if(store.size() > MAX){
			try {
				full.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		store.add(be);
		
		full.signalAll();
		empty.signalAll();
		lock.unlock();
	}
	
	public void popAndSend(){
		lock.lock();
		
		if(store.size() == 0){
			try {
				empty.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		Object be = store.removeFirst();
		empty.signalAll();
		full.signalAll();
		lock.unlock();
		
		sendToClient(JSONObject.toJSON(be));
	}

	@Override
	public void run() {
		while(true){
			this.popAndSend();
		}
		
	}
	/**
	 * 
	 * @param ne
	 * @param add 添加还是删除
	 */
	public void putNe(CfgNe ne, boolean add){
		BaseEvent be = new BaseEvent();
		be.setAction(add?BaseEvent.ACTION_VALUE_ON:BaseEvent.ACTION_VALUE_OFF);
		be.setType(BaseEvent.TYPE_CREATE_NE);
		be.setEntity(ne);
		//先处理告警，再处理网元
		if(!add){
			List<AlarmCurrent> list = ne.getAcurlist();
			for(AlarmCurrent a : list){
				putAlarm(a, false);
			}
		}
		
		put(be);
	}
	
	public void putSite(CfgSite site, boolean add){
		BaseEvent be = new BaseEvent();
		be.setAction(add?BaseEvent.ACTION_VALUE_ON:BaseEvent.ACTION_VALUE_OFF);
		be.setType(BaseEvent.TYPE_CREATE_SITE);
		be.setEntity(site);
		put(be);
	}
	
	public void putAlarm(AlarmCurrent alarm, boolean add){
		BaseEvent be = new BaseEvent();
		be.setAction(add?BaseEvent.ACTION_VALUE_ON:BaseEvent.ACTION_VALUE_OFF);
		be.setType(BaseEvent.TYPE_ALARM_NE);
		be.setEntity(alarm);
		put(be);
	}
}
